<?php
/**
 * Created by PhpStorm.
 * User: 65736
 * Date: 2019/2/28 0028
 * Time: 16:44
 */

namespace app\command;


use app\common\library\CommonFun;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;

abstract class Common extends Command
{
    /**
     * 开始执行时间
     * @var int
     */
    var $start_time;

    /**
     * 完成时间
     * @var int
     */
    var $end_time;

    /**
     * 是否显示执行时间
     * @var bool
     */
    var $cost_time = true;

    /**
     * 命令配置
     */
    protected function configure()
    {
        // 获取当前执行类的名称
        $class =  strtolower( CommonFun::get_class_name($this,false ) );
        // 设置命令名称
        $this->setName( "cli:{$class}" );
        // 环境标示选项
        $this->addOption('env','null', Option::VALUE_REQUIRED, '环境标示');
        // 是否显示执行时间
        $this->addOption('cost_time');
        // 执行对象配置
        $this->config();
    }

    /**
     * 初始化方法
     * 此方法在 interact() 和 execute() 方法之前执行。
     * 它的主要作用是初始化那些用在命令其余方法中的变量
     * @param Input $input
     * @param Output $output
     */
    protected function initialize(Input $input, Output $output)
    {
        // 记录开始时间戳
        $this->start_time  = microtime(true);
        // 获取是否显示执行时间
        $this->cost_time = $input->getOption("cost_time");
        if ( $this->cost_time ) {
            $start_msg = "Start " . $this->getName() . " " .date ( "Y-m-d H:i:s" );
            $output->writeln($start_msg);
        }
    }

    /**
     * 验证方法
     * 此方法在 initialize() 之后、 execute() 之前执行。
     * 它的作用是检查是否错失了某些选项/参数，然后以互动方式向用户请求这些值。
     * 这是你可以问询错失的选项/参数的最后一个地方。此后，丢失的选项/参数将导致一个错误。
     * @param Input $input
     * @param Output $output
     */
    protected function interact(Input $input, Output $output)
    {
        parent::interact($input, $output);
    }

    /**
     * 执行命令
     * @param Input $input
     * @param Output $output
     * @return int|null|void
     */
    protected function execute(Input $input, Output $output)
    {
        // 执行对象命令
        $this->exec($input, $output);
        // 结束时间
        $this->end_time = microtime(true);
        $cost_time = bcsub( $this->end_time, $this->start_time , 4 );
        // 是否显示结束时间
        if ( $this->cost_time ) {
            $output->writeln("CostTime:" . $cost_time . "s");
            $output->writeln("Finished " . date ( "Y-m-d H:i:s" ));
            $output->writeln("Execute Result:success");
        }
    }

    /**
     * 命令配置
     * @return mixed
     */
    abstract protected function config();

    /**
     * 执行命令(实际执行的方法体)
     * @param Input $input
     * @param Output $output
     * @return int|null|void
     */
    abstract protected function exec( Input $input, Output $output );

}